use std::result::Result;
use actix_web::web;
use crate::models::login;
use mysql_async::prelude::Queryable;
use mysql_async::params;
use std::io;
use std::fs::OpenOptions;
use crate::from::create;


pub async fn select_all(db: web::Data<mysql_async::Pool>) -> Result<Vec<login>,Box<std::error::Error>> {
    let conn = db.get_conn().await?;
    let result = conn.prep_exec("select * from login", ()).await?;
    let (_, logins) = result.map_and_drop(|row| {
        let id:Option<i32> = row.get("id");
        let username:Option<String> = row.get("username");
        let password:Option<String> = row.get("password");

        let mut login:login = login {
            id: 0,
            username: "".to_string(),
            password: "".to_string()
        };

        if let Some(some) = id {
            login.id = some;
        };

        if let Some(some) = username {
            login.username = some;
        }

        if let Some(some) = password {
            login.password = some;
        }

        login
    }).await?;

    Ok(logins)
}

pub async fn select_one(db: web::Data<mysql_async::Pool>,id :i32) -> Result<login,Box<std::error::Error>> {
    let conn = db.get_conn().await?;
    println!("{}",id);
    let result = conn.prep_exec("select * from login where id = :id", params! {
        "id"=>id
    }).await?;
    let (_, logins) = result.map_and_drop(|row| {
        let id:Option<i32> = row.get("id");
        let username:Option<String> = row.get("username");
        let password:Option<String> = row.get("password");

        let mut login:login = login {
            id: 0,
            username: "".to_string(),
            password: "".to_string()
        };

        if let Some(some) = id {
            login.id = some;
        };

        if let Some(some) = username {
            login.username = some;
        }

        if let Some(some) = password {
            login.password = some;
        }

        login
    }).await?;

    if logins.len() == 1{
        Ok(logins[0].clone())
    }
    else {
        Err(Box::new(io::Error::new(io::ErrorKind::Other,"Not Find")))
    }
}

pub async fn create_one(db: web::Data<mysql_async::Pool>,info : create) -> Result<i32,Box<std::error::Error>>{
    let conn = db.get_conn().await?;
    let result = conn.prep_exec("select * from login where username = :username", params! {
        "username"=> info.username.clone()
    }).await?;

    if result.is_empty(){
        return Err(Box::new(io::Error::new(io::ErrorKind::Other,"重复")));
    }

    let conn = db.get_conn().await?;
    let result = conn.prep_exec("insert into login(username,password) values (:username,:password)",params! {
        "username" => info.username.clone(),
        "password" => info.password.clone(),
    }).await?;

    if let Some(id) = result.last_insert_id() {
        return Ok(id as i32);
    }
    else {
        return Err(Box::new(io::Error::new(io::ErrorKind::Other,"插入失败")));
    }
}

pub async fn updata_one(db: web::Data<mysql_async::Pool>,info : crate::models::login) -> Result<(),Box<std::error::Error>>{
    let conn = db.get_conn().await?;
    let result = conn.prep_exec("select * from login where id = :id", params! {
        "id"=> info.id
    }).await?;

    if result.is_empty(){
        return Err(Box::new(io::Error::new(io::ErrorKind::Other,"id错误")));
    }

    let conn = db.get_conn().await?;
    let result = conn.prep_exec("update login set username = :username,password = :password where id = :id",params! {
        "username" => info.username.clone(),
        "password" => info.password.clone(),
        "id" => info.id,
    }).await?;

    if 1 == result.affected_rows() {
        return Ok(());
    }
    else {
        return Err(Box::new(io::Error::new(io::ErrorKind::Other,"更新失败")));
    }
}

pub async fn delete_one(db: web::Data<mysql_async::Pool>,info : crate::from::id) -> Result<(),Box<std::error::Error>>{
    let conn = db.get_conn().await?;
    let result = conn.prep_exec("select * from login where id = :id", params! {
        "id"=> info.id
    }).await?;

    if result.is_empty(){
        return Err(Box::new(io::Error::new(io::ErrorKind::Other,"id错误")));
    }

    let conn = db.get_conn().await?;
    let result = conn.prep_exec("delete from login where id = :id",params! {
        "id" => info.id,
    }).await?;

    if 1 == result.affected_rows() {
        return Ok(());
    }
    else {
        return Err(Box::new(io::Error::new(io::ErrorKind::Other,"失败删除")));
    }
}